package com.zh.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zh.common.ErrorCode;
import com.zh.constant.PriorityConstant;
import com.zh.constant.TaskConstant;
import com.zh.domain.Model.AttachCount;
import com.zh.domain.dto.task.AddTaskRequest;
import com.zh.domain.dto.task.PageTaskDynamicRequest;
import com.zh.domain.dto.task.PageTaskRequest;
import com.zh.domain.dto.task.UpdateTaskRequest;
import com.zh.domain.entity.*;
import com.zh.domain.vo.task.TaskDynamicVo;
import com.zh.domain.vo.task.TaskVo;
import com.zh.domain.vo.user.UserVO;
import com.zh.exception.ThrowUtils;
import com.zh.job.TaskManager;
import com.zh.mapper.AttachesMapper;
import com.zh.mapper.TaskMapper;
import com.zh.service.*;
import org.springframework.aop.framework.AopContext;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author Administrator
 * @description 针对表【tasks(任务表)】的数据库操作Service实现
 * @createDate 2025-02-09 16:24:10
 */
@Service
public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task>
        implements TaskService {

    @Resource
    private UserService userService;
    @Resource
    private ProjectDynamicsService projectDynamicsService;
    @Resource
    private TaskDynamicsService taskDynamicsService;
    @Lazy
    @Resource
    private MilestoneService milestoneService;
    @Resource
    @Lazy
    private RequirementsService requirementsService;
    @Resource
    @Lazy
    private IterationService iterationService;
    @Resource
    @Lazy
    private ProjectService projectService;
    @Resource
    private MessageService messageService;
    @Resource
    private TaskMapper taskMapper;
    @Resource
    private AttachesMapper attachesMapper;

    @Override
    @Transactional
    public Boolean addTask(AddTaskRequest addTaskRequest) {
        int loginId = StpUtil.getLoginIdAsInt();
        TaskService proxy = (TaskService) AopContext.currentProxy();
        //1.参数校验
        Integer proId = addTaskRequest.getProId();
        Integer iterId = addTaskRequest.getIterId();
        Integer mileId = addTaskRequest.getMileId();
        Integer reqId = addTaskRequest.getReqId();
        Integer ownerId = addTaskRequest.getOwnerId();
        String title = addTaskRequest.getTitle();
        String description = addTaskRequest.getDescription();
        String remark = addTaskRequest.getRemark();
        Integer priority = addTaskRequest.getPriority();
        ThrowUtils.throwIf(null == proId, ErrorCode.PARAMS_ERROR, "项目id不能为空");
        ThrowUtils.throwIf(StrUtil.isEmpty(title) || title.length() > 100, ErrorCode.PARAMS_ERROR, "标题字数<100");
        ThrowUtils.throwIf(!PriorityConstant.validPriority(priority), ErrorCode.PARAMS_ERROR, "优先级错误");
        //2. 生成编号 插入数据
        Task task = new Task();
        LambdaQueryWrapper<Task> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Task::getProId, proId);
        if (null != mileId) {
            queryWrapper.eq(Task::getMileId, mileId);
        }
        if (null != iterId) {
            queryWrapper.eq(Task::getIterId, iterId);
        }
        if (null != reqId) {
            queryWrapper.eq(Task::getReqId, reqId);
        }
        if (null != ownerId) {
            queryWrapper.eq(Task::getOwnerId, ownerId);
        }
        Long count = taskMapper.selectCount(queryWrapper);
        StringBuilder code = new StringBuilder();
        code.append("T-");
        code.append("P").append(proId).append("-");
        if (null != mileId) {
            code.append("M").append(mileId).append("-");
        }
        if (null != iterId) {
            code.append("I").append(iterId).append("-");
        }
        if (null != reqId) {
            code.append("R").append(reqId).append("-");
        }
        if (null != ownerId) {
            code.append("O").append(ownerId).append("-");
        }
        code.append(count + 1);
        BeanUtil.copyProperties(addTaskRequest, task);
        task.setStatus(0);
        task.setCode(code.toString());
        task.setCreateBy(loginId);
        task.setUpdateBy(loginId);
        task.setDeleted(0);
        boolean saved = proxy.save(task);
        //3. 发送消息、动态
        if (saved) {
            requirementsService.updateProcessById(task.getReqId());
            iterationService.updateProcessById(task.getIterId());
            milestoneService.updateProcessById(task.getMileId());
            projectService.updateProcessById(task.getProId());
        }
        Task insertedTask = getById(task.getId());
        TaskManager.execute(() -> proxy.sendMessageAndDynamicWhenAdd(loginId, insertedTask));
        return saved;
    }


    @Override
    @Transactional
    public void sendMessageAndDynamicWhenAdd(Integer operatorId, Task newTask) {
        Integer createBy = newTask.getCreateBy();
        UserVO creator = userService.getUserVoById(createBy);
        ProjectDynamics dynamics = new ProjectDynamics(true);
        dynamics.setProId(newTask.getProId());
        String content;
        if (newTask.getOwnerId() != null) {
            UserVO ownerVO = userService.getUserVoById(newTask.getOwnerId());
            content = creator.getName() + "为" + ownerVO.getName() + "分配了任务 " + newTask.getTitle() + '.';
        } else {
            content = creator.getName() + "创建了任务" + newTask.getTitle() + "-" + newTask.getId() + '.';
        }
        dynamics.setContent(content);
        dynamics.setCreateBy(operatorId);
        dynamics.setUpdateBy(operatorId);
        projectDynamicsService.save(dynamics);
        TaskDynamics taskDynamics = new TaskDynamics();
        taskDynamics.setTaskId(newTask.getId());
        taskDynamics.setContent(content);
        taskDynamics.setCreateAt(LocalDateTime.now());
        taskDynamics.setCreateBy(operatorId);
        taskDynamics.setUpdateAt(LocalDateTime.now());
        taskDynamics.setUpdateBy(operatorId);
        taskDynamicsService.save(taskDynamics);
        //发送消息
        Message message = new Message();
        String messageContent = creator.getName() +
                " 为你分配了任务 " +
                newTask.getTitle() +
                ",请及时处理.";
        message.setContent(messageContent);
        message.setSendId(creator.getId());
        message.setCreateAt(LocalDateTime.now());
        message.setCreateBy(operatorId);
        message.setUpdateAt(LocalDateTime.now());
        message.setUpdateBy(operatorId);
        message.setNoticeType(0);
        message.setType(2);
        Map<String, Object> paramsToOwner = new HashMap<>();
        paramsToOwner.put("taskId", Optional.ofNullable(newTask.getId()).map(Object::toString).orElse(null));
        paramsToOwner.put("proId", Optional.ofNullable(newTask.getProId()).map(Object::toString).orElse(null));
        paramsToOwner.put("iterId", Optional.ofNullable(newTask.getIterId()).map(Object::toString).orElse(null));
        paramsToOwner.put("milestoneId", Optional.ofNullable(newTask.getMileId()).map(Object::toString).orElse(null));
        paramsToOwner.put("reqId", Optional.ofNullable(newTask.getReqId()).map(Object::toString).orElse(null));
        paramsToOwner.put("payloadType", "task");
        paramsToOwner.put("title", newTask.getTitle());
        message.setParams(paramsToOwner);
        message.setStatus(1);
        message.setDeleted(0);
        messageService.sendMessage(message, List.of(newTask.getOwnerId()));
    }

    @Override
    @Transactional
    public Boolean updateTask(UpdateTaskRequest updateTaskRequest) {
        int loginId = StpUtil.getLoginIdAsInt();
        return updateTask(loginId, updateTaskRequest);
    }

    @Override
    @Transactional
    public Boolean updateTask(Integer userId, UpdateTaskRequest updateTaskRequest) {
        Integer loginId = userId;
        TaskService proxy = (TaskService) AopContext.currentProxy();
        //1.校验参数
        Integer id = updateTaskRequest.getId();
        Integer proId = updateTaskRequest.getProId();
        Integer mileId = updateTaskRequest.getMileId();
        Integer iterId = updateTaskRequest.getIterId();
        Integer reqId = updateTaskRequest.getReqId();
        Integer ownerId = updateTaskRequest.getOwnerId();
        String title = updateTaskRequest.getTitle();
        String description = updateTaskRequest.getDescription();
        String remark = updateTaskRequest.getRemark();
        Integer priority = updateTaskRequest.getPriority();
        Integer status = updateTaskRequest.getStatus();
        LocalDateTime startTime = updateTaskRequest.getStartTime();
        LocalDateTime endTime = updateTaskRequest.getEndTime();
        ThrowUtils.throwIf(startTime != null && endTime != null && startTime.isAfter(endTime), ErrorCode.PARAMS_ERROR, "开始时间不能晚于结束时间");
        ThrowUtils.throwIf(null == id, ErrorCode.PARAMS_ERROR, "任务id不能为空");
        ThrowUtils.throwIf(StrUtil.isNotEmpty(title) && title.length() > 100, ErrorCode.PARAMS_ERROR, "标题字数<100");
        ThrowUtils.throwIf(priority != null && !PriorityConstant.validPriority(priority), ErrorCode.PARAMS_ERROR, "优先级错误");
        synchronized (id) {
            Task oldTask = proxy.getById(id);
            Task updateTask = new Task();
            LambdaUpdateWrapper<Task> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Task::getId, id);
            updateWrapper.set(null != ownerId, Task::getOwnerId, ownerId);
            updateWrapper.set(null != title, Task::getTitle, title);
            updateWrapper.set(null != description, Task::getDescription, description);
            updateWrapper.set(null != remark, Task::getRemark, remark);
            updateWrapper.set(null != priority, Task::getPriority, priority);
            updateWrapper.set(null != startTime, Task::getStartTime, startTime);
            updateWrapper.set(null != endTime, Task::getEndTime, endTime);
            updateWrapper.set(null != status, Task::getStatus, status);
            //如果更新状态为已完成，则更新完成时间,触发更新项目、里程碑、迭代、需求服务
            updateWrapper.set(status != null && status == 4, Task::getCompleteTime, LocalDateTime.now());
            updateWrapper.set(Task::getUpdateAt, LocalDateTime.now());
            updateWrapper.set(Task::getUpdateBy, loginId);
            // 关联里程碑、迭代、需求的修改
            if (mileId != null && mileId != -1) {
                updateWrapper.set(Task::getMileId, mileId);
            } else if (mileId == null) {
                updateWrapper.set(Task::getMileId, null);
            }
            if (iterId != null && iterId != -1) {
                updateWrapper.set(Task::getIterId, iterId);
            } else if (iterId == null) {
                updateWrapper.set(Task::getIterId, null);
            }
            if (reqId != null && reqId != -1) {
                updateWrapper.set(Task::getReqId, reqId);
            } else if (reqId == null) {
                updateWrapper.set(Task::getReqId, null);
            }
            //3.更新数据
            boolean updated = proxy.update(updateTask, updateWrapper);
            Task updatedTask = proxy.getById(id);
            //4. 发送消息、动态、触发更新项目、里程碑、迭代、需求服务
            if (updated) {
                requirementsService.updateProcessById(updatedTask.getReqId());
                iterationService.updateProcessById(updatedTask.getIterId());
                milestoneService.updateProcessById(updatedTask.getMileId());
                projectService.updateProcessById(updatedTask.getProId());
                TaskManager.execute(() -> sendMessageAndDynamicWhenUpdate(loginId, oldTask, updatedTask));
            }
            return updated;
        }
    }

    @Override
    @Transactional
    public void sendMessageAndDynamicWhenUpdate(Integer operatorId, Task oldTask, Task newTask) {
        Integer updateBy = newTask.getUpdateBy();
        UserVO updater = userService.getUserVoById(updateBy);
        ProjectDynamics templateDynamics = new ProjectDynamics(true);
        templateDynamics.setProId(newTask.getProId());
        templateDynamics.setCreateBy(operatorId);
        templateDynamics.setUpdateBy(operatorId);
        List<ProjectDynamics> projectDynamicsList = new ArrayList<>();
        List<TaskDynamics> taskDynamicsList = new ArrayList<>();
        List<String> contentList = new ArrayList<>();
        generateDynamicContent(oldTask, newTask, contentList, updater);
        contentList.forEach(dynamicContent -> {
            ProjectDynamics dynamics = BeanUtil.copyProperties(templateDynamics, ProjectDynamics.class);
            dynamics.setContent(dynamicContent);
            projectDynamicsList.add(dynamics);
            TaskDynamics taskDynamics = new TaskDynamics();
            taskDynamics.setTaskId(newTask.getId());
            taskDynamics.setContent(dynamicContent);
            taskDynamics.setCreateAt(LocalDateTime.now());
            taskDynamics.setCreateBy(operatorId);
            taskDynamics.setUpdateAt(LocalDateTime.now());
            taskDynamics.setUpdateBy(operatorId);
            taskDynamics.setStatus(1);
            taskDynamics.setDeleted(0);
            taskDynamicsList.add(taskDynamics);
        });
        projectDynamicsService.saveBatch(projectDynamicsList);
        taskDynamicsService.saveBatch(taskDynamicsList);
        // 切换了负责人发送消息
        if (!Objects.equals(oldTask.getOwnerId(), newTask.getOwnerId())) {
            UserVO oldOwner = userService.getUserVoById(oldTask.getOwnerId());
            UserVO newOwner = userService.getUserVoById(newTask.getOwnerId());
            Message messageToOldOwner = new Message();
            //发送给旧负责人
            String messageContent = updater.getName() +
                    " 将你负责的任务 " +
                    newTask.getTitle() +
                    "移交给 " +
                    newOwner.getName();
            messageToOldOwner.setContent(messageContent);
            messageToOldOwner.setSendId(updater.getId());
            messageToOldOwner.setCreateAt(LocalDateTime.now());
            messageToOldOwner.setCreateBy(operatorId);
            messageToOldOwner.setUpdateAt(LocalDateTime.now());
            messageToOldOwner.setUpdateBy(operatorId);
            messageToOldOwner.setNoticeType(0);
            messageToOldOwner.setType(2);
            Map<String, Object> paramsToOldOwner = new HashMap<>();
            paramsToOldOwner.put("taskId", Optional.ofNullable(newTask.getId()).map(Object::toString).orElse(null));
            paramsToOldOwner.put("proId", Optional.ofNullable(newTask.getProId()).map(Object::toString).orElse(null));
            paramsToOldOwner.put("iterId", Optional.ofNullable(newTask.getIterId()).map(Object::toString).orElse(null));
            paramsToOldOwner.put("milestoneId", Optional.ofNullable(newTask.getMileId()).map(Object::toString).orElse(null));
            paramsToOldOwner.put("reqId", Optional.ofNullable(newTask.getReqId()).map(Object::toString).orElse(null));
            paramsToOldOwner.put("payloadType", "task");
            paramsToOldOwner.put("title", newTask.getTitle());
            messageToOldOwner.setParams(paramsToOldOwner);
            messageToOldOwner.setStatus(1);
            messageToOldOwner.setDeleted(0);
            messageService.sendMessage(messageToOldOwner, List.of(oldOwner.getId()));
            // 发送给新负责人
            Message messageToNewOwner = new Message();
            String messageContent1 = updater.getName() +
                    " 为你分配了任务 " +
                    newTask.getTitle() +
                    ",请及时处理.";
            messageToNewOwner.setContent(messageContent1);
            messageToNewOwner.setSendId(updater.getId());
            messageToNewOwner.setCreateAt(LocalDateTime.now());
            messageToNewOwner.setCreateBy(operatorId);
            messageToNewOwner.setUpdateAt(LocalDateTime.now());
            messageToNewOwner.setUpdateBy(operatorId);
            messageToNewOwner.setNoticeType(0);
            messageToNewOwner.setType(2);
            Map<String, Object> paramsToNewOwner = new HashMap<>();
            paramsToNewOwner.put("taskId", Optional.ofNullable(newTask.getId()).map(Object::toString).orElse(null));
            paramsToNewOwner.put("proId", Optional.ofNullable(newTask.getProId()).map(Object::toString).orElse(null));
            paramsToNewOwner.put("iterId", Optional.ofNullable(newTask.getIterId()).map(Object::toString).orElse(null));
            paramsToNewOwner.put("milestoneId", Optional.ofNullable(newTask.getMileId()).map(Object::toString).orElse(null));
            paramsToNewOwner.put("reqId", Optional.ofNullable(newTask.getReqId()).map(Object::toString).orElse(null));
            paramsToNewOwner.put("payloadType", "task");
            paramsToNewOwner.put("title", newTask.getTitle());
            messageToOldOwner.setParams(paramsToNewOwner);
            messageToNewOwner.setStatus(1);
            messageToNewOwner.setDeleted(0);
            messageService.sendMessage(messageToNewOwner, List.of(newOwner.getId()));
        }
    }

    private void generateDynamicContent(Task oldTask, Task newTask, List<String> contentList, UserVO updater) {
        String content;

        if (!Objects.equals(oldTask.getOwnerId(), newTask.getOwnerId())) {
            UserVO oldOwner = userService.getUserVoById(oldTask.getOwnerId());
            UserVO newOwner = userService.getUserVoById(newTask.getOwnerId());
            if (oldOwner != null && newOwner != null) {
                content = updater.getName() + "将任务 " + newTask.getTitle() + "负责人从 " + oldOwner.getName() + " 切换为 " + newOwner.getName() + '.';
                contentList.add(content);
            }
        }
        Integer oldTaskStatus = oldTask.getStatus();
        Integer newTaskStatus = newTask.getStatus();
        if (!Objects.equals(oldTaskStatus, newTaskStatus)) {
            if (null != newTaskStatus && null != oldTaskStatus) {
                content = updater.getName() + "将任务 " + newTask.getTitle() + "状态从" + TaskConstant.getStatusName(oldTask.getStatus()) + " 切换为 " + TaskConstant.getStatusName(newTask.getStatus()) + '.';
                contentList.add(content);
            }
        }
        Integer oldTaskPriority = oldTask.getPriority();
        Integer newTaskPriority = newTask.getPriority();
        if (!Objects.equals(oldTaskPriority, newTaskPriority)) {
            if (null != newTaskPriority && null != oldTaskPriority) {
                content = updater.getName() + "将任务 " + newTask.getTitle() + "优先级从" + PriorityConstant.getPriorityName(oldTask.getPriority()) + " 切换为 " + PriorityConstant.getPriorityName(newTask.getPriority()) + '.';
                contentList.add(content);
            }
        }
        String oldTaskTitle = oldTask.getTitle();
        String newTaskTitle = newTask.getTitle();
        if (!Objects.equals(oldTask.getTitle(), newTask.getTitle())) {
            if (null != newTaskTitle && null != oldTaskTitle) {
                content = updater.getName() + "将任务标题从 " + oldTask.getTitle() + " 修改为 " + newTask.getTitle() + '.';
                contentList.add(content);
            }
        }
        if (!Objects.equals(oldTask.getMileId(), newTask.getMileId())) {
            Milestone oldMilestone = milestoneService.getById(oldTask.getMileId());
            Milestone newMilestone = milestoneService.getById(newTask.getMileId());
            if (oldMilestone != null && newMilestone != null) {
                content = updater.getName() + "将任务 " + newTask.getTitle() + "从里程碑 " + oldMilestone.getTitle() + " 移动到里程碑 " + newMilestone.getTitle() + '.';
                contentList.add(content);
            }
        }
        if (!Objects.equals(oldTask.getIterId(), newTask.getIterId())) {
            Iteration oldIteration = iterationService.getById(oldTask.getIterId());
            Iteration newIteration = iterationService.getById(newTask.getIterId());
            if (oldIteration != null && newIteration != null) {
                content = updater.getName() + "将任务 " + newTask.getTitle() + "从迭代 " + oldIteration.getTitle() + " 移动到迭代 " + newIteration.getTitle() + '.';
                contentList.add(content);
            }
        }
        if (!Objects.equals(oldTask.getReqId(), newTask.getReqId())) {
            Requirements oldRequirement = requirementsService.getById(oldTask.getReqId());
            Requirements newRequirement = requirementsService.getById(newTask.getReqId());
            if (oldRequirement != null && newRequirement != null) {
                content = updater.getName() + "将任务 " + newTask.getTitle() + "从需求 " + oldRequirement.getTitle() + " 移动到需求 " + newRequirement.getTitle() + '.';
                contentList.add(content);
            }
        }
        LocalDateTime oleStartTime = oldTask.getStartTime();
        LocalDateTime newStartTime = newTask.getStartTime();
        if (!Objects.equals(oleStartTime, newStartTime)) {
            //格式化时间
            String oldStartTimeStr = oldTask.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String newStartTimeStr = newTask.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            content = updater.getName() + "将任务 " + newTask.getTitle() + " 开始时间从 " + oldStartTimeStr + " 修改为 " + newStartTimeStr + '.';
            contentList.add(content);
        }
        LocalDateTime oleEndTime = oldTask.getEndTime();
        LocalDateTime newEndTime = newTask.getEndTime();
        if (!Objects.equals(oleEndTime, newEndTime)) {
            String oldEndTimeStr = oldTask.getEndTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String newEndTimeStr = newTask.getEndTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            content = updater.getName() + "将任务 " + newTask.getTitle() + " 结束时间从 " + oldEndTimeStr + " 修改为 " + newEndTimeStr + '.';
            contentList.add(content);
        }
        if (!Objects.equals(oldTask.getDescription(), newTask.getDescription())) {
            content = updater.getName() + "修改了任务 " + newTask.getTitle() + " 描述.";
            contentList.add(content);
        }
        if (!Objects.equals(oldTask.getRemark(), newTask.getRemark())) {
            content = updater.getName() + "修改了任务 " + newTask.getTitle() + " 备注.";
            contentList.add(content);
        }
    }

    @Override
    public Page<TaskVo> pageTasks(PageTaskRequest pageTaskRequest) {
        TaskService proxy = (TaskService) AopContext.currentProxy();
        //1. 参数查询
        Integer mileId = pageTaskRequest.getMileId();
        Integer proId = pageTaskRequest.getProId();
        Boolean isUnOwned = pageTaskRequest.getUnOwned();
        Integer status = pageTaskRequest.getStatus();
        ThrowUtils.throwIf(null == proId, ErrorCode.PARAMS_ERROR);
        pageTaskRequest.standardizeSize();
        Integer current = pageTaskRequest.getCurrent();
        Integer pageSize = pageTaskRequest.getPageSize();
        LambdaQueryWrapper<Task> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Task::getProId, proId)
                .eq(null != status, Task::getStatus, status)
                .isNull(isUnOwned, Task::getOwnerId)
                .eq(Task::getDeleted, 0);
        Page<Task> page = new Page<>(current, pageSize);
        Page<Task> taskPage = proxy.page(page);
        List<Task> records = taskPage.getRecords();

        List<Integer> userIdList = records.stream()
                .flatMap(task -> Stream.of(task.getOwnerId(), task.getCreateBy()))
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        List<UserVO> userVOList = userService.listUserVoByIds(userIdList);
        Map<Integer, UserVO> userVOMap = userVOList.stream().collect(Collectors.toMap(UserVO::getId, userVO -> userVO));
        List<TaskVo> TaskVoList = records.stream().map(task -> {
            TaskVo taskVo = BeanUtil.copyProperties(task, TaskVo.class);
            taskVo.setOwner(userVOMap.get(task.getOwnerId()));
            taskVo.setCreator(userVOMap.get(task.getCreateBy()));
            return taskVo;
        }).collect(Collectors.toList());
        Page<TaskVo> taskVoPage = new Page<>(current, pageSize);
        BeanUtil.copyProperties(taskPage, taskVoPage);
        taskVoPage.setRecords(TaskVoList);
        return taskVoPage;
    }

    @Override
    public List<TaskVo> listByReqId(Integer reqId) {
        if (Objects.isNull(reqId)) {
            return Collections.emptyList();
        }
        LambdaQueryWrapper<Task> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Task::getReqId, reqId)
                .eq(Task::getDeleted, 0)
                .orderByAsc(Task::getId)
                .orderByAsc(Task::getCreateAt);
        List<Task> tasks = taskMapper.selectList(queryWrapper);
        if (tasks.isEmpty()) {
            return Collections.emptyList();
        }
        //获取附件数量
        List<Integer> taskIdList = tasks.stream().map(Task::getId).collect(Collectors.toList());
        List<AttachCount> attachCounts = new ArrayList<>();
        Map<Integer, AttachCount> attachCountMap = new HashMap<>();
        if (!taskIdList.isEmpty()) {
            attachCounts = attachesMapper.countByTaskIdList(taskIdList);
        }
        if (!attachCounts.isEmpty()) {
            attachCounts.forEach(attachCount -> attachCountMap.put(attachCount.getTypeId(), attachCount));
        }
        // 查询用户信息
        List<Integer> userIdList = tasks.stream()
                .flatMap(task -> Stream.of(task.getOwnerId(), task.getCreateBy(), task.getUpdateBy()))
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        List<UserVO> userVOList = userService.listUserVoByIds(userIdList);
        Map<Integer, UserVO> userVOMap = userVOList.stream().collect(Collectors.toMap(UserVO::getId, userVO -> userVO));
        return tasks.stream().map(task -> {
            TaskVo taskVo = BeanUtil.copyProperties(task, TaskVo.class);
            taskVo.setOwner(userVOMap.get(task.getOwnerId()));
            taskVo.setCreator(userVOMap.get(task.getCreateBy()));
            taskVo.setUpdater(userVOMap.get(task.getUpdateBy()));
            AttachCount attachCount = attachCountMap.get(task.getId());
            taskVo.setAttachCount(attachCount != null ? attachCount.getCount() : 0);
            return taskVo;
        }).collect(Collectors.toList());
    }

    @Override
    public List<TaskVo> listByIterationId(Integer iterId) {
        if (Objects.isNull(iterId)) {
            return Collections.emptyList();
        }
        LambdaQueryWrapper<Task> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Task::getIterId, iterId);
        queryWrapper.eq(Task::getDeleted, 0)
                .orderByAsc(Task::getPriority)
                .orderByAsc(Task::getStartTime)
                .orderByAsc(Task::getEndTime)
                .orderByAsc(Task::getStatus)
                .orderByAsc(Task::getCreateAt)
                .orderByAsc(Task::getUpdateAt)
                .orderByAsc(Task::getId);
        List<Task> taskList = taskMapper.selectList(queryWrapper);
        if (taskList.isEmpty()) {
            return Collections.emptyList();
        }
        // 获取用户信息
        List<Integer> userIdList = taskList.stream()
                .flatMap(task -> Stream.of(task.getOwnerId(), task.getCreateBy(), task.getUpdateBy()))
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());

        Map<Integer, UserVO> userVOMap = userService.listUserVoByIds(userIdList).stream()
                .collect(Collectors.toMap(UserVO::getId, userVO -> userVO));

        return taskList.stream().map(task -> {
            TaskVo taskVo = BeanUtil.copyProperties(task, TaskVo.class);
            taskVo.setOwner(userVOMap.get(task.getOwnerId()));
            taskVo.setCreator(userVOMap.get(task.getCreateBy()));
            taskVo.setUpdater(userVOMap.get(task.getUpdateBy()));
            return taskVo;
        }).collect(Collectors.toList());
    }

    @Override
    public List<TaskVo> listByMileStoneId(Integer mileId) {
        if (Objects.isNull(mileId)) {
            return Collections.emptyList();
        }
        LambdaQueryWrapper<Task> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Task::getMileId, mileId)
                .eq(Task::getDeleted, 0)
                .orderByAsc(Task::getPriority)
                .orderByAsc(Task::getStartTime)
                .orderByAsc(Task::getEndTime)
                .orderByAsc(Task::getStatus)
                .orderByAsc(Task::getCreateAt)
                .orderByAsc(Task::getUpdateAt)
                .orderByAsc(Task::getId);
        List<Task> taskList = taskMapper.selectList(queryWrapper);
        if (taskList.isEmpty()) {
            return Collections.emptyList();
        }
        // 获取用户信息
        List<Integer> userIdList = taskList.stream()
                .flatMap(task -> Stream.of(task.getOwnerId(), task.getCreateBy(), task.getUpdateBy()))
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());

        Map<Integer, UserVO> userVOMap = userService.listUserVoByIds(userIdList).stream()
                .collect(Collectors.toMap(UserVO::getId, userVO -> userVO));

        return taskList.stream().map(task -> {
            TaskVo taskVo = BeanUtil.copyProperties(task, TaskVo.class);
            taskVo.setOwner(userVOMap.get(task.getOwnerId()));
            taskVo.setCreator(userVOMap.get(task.getCreateBy()));
            taskVo.setUpdater(userVOMap.get(task.getUpdateBy()));
            return taskVo;
        }).collect(Collectors.toList());
    }

    @Override
    public List<TaskVo> listByProId(Integer proId) {
        if (Objects.isNull(proId)) {
            return Collections.emptyList();
        }
        LambdaQueryWrapper<Task> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Task::getProId, proId);
        queryWrapper.eq(Task::getDeleted, 0)
                .orderByAsc(Task::getPriority)
                .orderByAsc(Task::getStartTime)
                .orderByAsc(Task::getEndTime)
                .orderByAsc(Task::getStatus)
                .orderByAsc(Task::getCreateAt)
                .orderByAsc(Task::getUpdateAt)
                .orderByAsc(Task::getId);
        List<Task> taskList = taskMapper.selectList(queryWrapper);
        if (taskList.isEmpty()) {
            return Collections.emptyList();
        }
        // 获取用户信息
        List<Integer> userIdList = taskList.stream()
                .flatMap(task -> Stream.of(task.getOwnerId(), task.getCreateBy(), task.getUpdateBy()))
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());

        Map<Integer, UserVO> userVOMap = userService.listUserVoByIds(userIdList).stream()
                .collect(Collectors.toMap(UserVO::getId, userVO -> userVO));

        return taskList.stream().map(task -> {
            TaskVo taskVo = BeanUtil.copyProperties(task, TaskVo.class);
            taskVo.setOwner(userVOMap.get(task.getOwnerId()));
            taskVo.setCreator(userVOMap.get(task.getCreateBy()));
            taskVo.setUpdater(userVOMap.get(task.getUpdateBy()));
            return taskVo;
        }).collect(Collectors.toList());
    }

    @Override
    public List<TaskVo> listByProIdAndOwnerId(Integer proId) {
        int loginId = StpUtil.getLoginIdAsInt();
        if (Objects.isNull(proId)) {
            return Collections.emptyList();
        }
        LambdaQueryWrapper<Task> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Task::getProId, proId)
                .eq(Task::getOwnerId, loginId)
                .isNull(Task::getReqId)
                .eq(Task::getDeleted, 0)
                .orderByAsc(Task::getPriority)
                .orderByAsc(Task::getEndTime)
                .orderByAsc(Task::getStartTime)
                .orderByAsc(Task::getStatus)
                .orderByAsc(Task::getCreateAt)
                .orderByAsc(Task::getUpdateAt)
                .orderByAsc(Task::getId);
        List<Task> taskList = taskMapper.selectList(queryWrapper);
        if (taskList.isEmpty()) {
            return Collections.emptyList();
        }
        // 获取用户信息
        List<Integer> userIdList = taskList.stream()
                .flatMap(task -> Stream.of(task.getOwnerId(), task.getCreateBy(), task.getUpdateBy()))
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());

        Map<Integer, UserVO> userVOMap = userService.listUserVoByIds(userIdList).stream()
                .collect(Collectors.toMap(UserVO::getId, userVO -> userVO));

        return taskList.stream().map(task -> {
            TaskVo taskVo = BeanUtil.copyProperties(task, TaskVo.class);
            taskVo.setOwner(userVOMap.get(task.getOwnerId()));
            taskVo.setCreator(userVOMap.get(task.getCreateBy()));
            taskVo.setUpdater(userVOMap.get(task.getUpdateBy()));
            return taskVo;
        }).collect(Collectors.toList());
    }

    @Override
    public List<TaskVo> listByIterationIdDirectly(Integer iterId) {
        return listTasksByCondition(null, iterId, null);
    }

    @Override
    public List<TaskVo> listByMileStoneIdDirectly(Integer mileId) {
        return listTasksByCondition(mileId, null, null);
    }

    @Override
    public List<TaskVo> listByProIdDirectly(Integer proId) {
        return listTasksByCondition(null, null, proId);
    }

    @Override
    public TaskVo getDetail(Integer id) {
        //1. 参数校验
        ThrowUtils.throwIf(null == id, ErrorCode.PARAMS_ERROR);
        Task task = taskMapper.selectById(id);
        //2.获取用户数据
        if (Objects.isNull(task)) {
            return null;
        }
        TaskVo taskVo = BeanUtil.copyProperties(task, TaskVo.class);
        UserVO creator = userService.getUserVoById(task.getCreateBy());
        UserVO owner = userService.getUserVoById(task.getOwnerId());
        UserVO updater = userService.getUserVoById(task.getUpdateBy());
        taskVo.setCreator(creator);
        taskVo.setOwner(owner);
        taskVo.setUpdater(updater);
        return taskVo;
    }

    @Override
    public Page<TaskDynamicVo> pageDynamics(PageTaskDynamicRequest pageTaskDynamicRequest) {
        //1. 参数校验
        Integer taskId = pageTaskDynamicRequest.getTaskId();
        ThrowUtils.throwIf(null == taskId, ErrorCode.PARAMS_ERROR);
        pageTaskDynamicRequest.standardizeSize();

        Integer current = pageTaskDynamicRequest.getCurrent();
        Integer pageSize = pageTaskDynamicRequest.getPageSize();
        Page<TaskDynamics> page = new Page<>(current, pageSize);
        LambdaQueryWrapper<TaskDynamics> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TaskDynamics::getTaskId, taskId)
                .orderByDesc(TaskDynamics::getCreateAt)
                .orderByDesc(TaskDynamics::getId);
        Page<TaskDynamics> taskDynamicsPage = taskDynamicsService.page(page, queryWrapper);
        List<TaskDynamics> records = taskDynamicsPage.getRecords();
        //2.获取用户数据
        if (records.isEmpty()) {
            return new Page<>();
        }
        List<Integer> userIdList = records.stream()
                .flatMap(taskDynamics -> Stream.of(taskDynamics.getCreateBy()))
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        List<UserVO> userVOList = userService.listUserVoByIds(userIdList);
        Map<Integer, UserVO> userVOMap = userVOList.stream().collect(Collectors.toMap(UserVO::getId, userVO -> userVO));
        List<TaskDynamicVo> resultList = new ArrayList<>();
        for (TaskDynamics taskDynamics : records) {
            TaskDynamicVo taskDynamicVo = BeanUtil.copyProperties(taskDynamics, TaskDynamicVo.class);
            taskDynamicVo.setCreator(userVOMap.get(taskDynamics.getCreateBy()));
            resultList.add(taskDynamicVo);
        }
        Page<TaskDynamicVo> taskDynamicVoPage = new Page<>(current, pageSize);
        BeanUtil.copyProperties(taskDynamicsPage, taskDynamicVoPage);
        taskDynamicVoPage.setRecords(resultList);
        return taskDynamicVoPage;
    }

    @Override
    @Transactional
    public boolean deleteTask(Integer taskId) {
        TaskService proxy = (TaskService) AopContext.currentProxy();
        int loginId = StpUtil.getLoginIdAsInt();
        Task task = proxy.getById(taskId);
        boolean removed = proxy.removeById(taskId);
        //删除后触发重新结算进度 / 动态
        if (removed) {
            TaskManager.execute(() -> {
                requirementsService.updateProcessById(task.getReqId());
                iterationService.updateProcessById(task.getIterId());
                milestoneService.updateProcessById(task.getMileId());
                projectService.updateProcessById(task.getProId());
            });

            TaskManager.execute(() -> {
                sendMessageAndDynamicWhenDelete(loginId, task);
            });
        }
        return removed;
    }

    @Override
    public void sendMessageAndDynamicWhenDelete(Integer operatorId, Task task) {
        UserVO operator = userService.getUserVoById(operatorId);
        ProjectDynamics dynamics = new ProjectDynamics(true);
        dynamics.setProId(task.getProId());
        String content;
        content = operator.getName() + "删除了任务" + task.getTitle() + "-" + task.getCode() + '.';
        dynamics.setContent(content);
        dynamics.setCreateBy(operatorId);
        dynamics.setUpdateBy(operatorId);
        projectDynamicsService.save(dynamics);
        TaskDynamics taskDynamics = new TaskDynamics();
        taskDynamics.setTaskId(task.getId());
        taskDynamics.setContent(content);
        taskDynamics.setCreateAt(LocalDateTime.now());
        taskDynamics.setCreateBy(operatorId);
        taskDynamics.setUpdateAt(LocalDateTime.now());
        taskDynamics.setUpdateBy(operatorId);
        taskDynamicsService.save(taskDynamics);
        //发送消息
        Message message = new Message();
        String messageContent = operator.getName() +
                " 删除了任务 " +
                task.getTitle() +
                ".";
        message.setContent(messageContent);
        message.setSendId(operator.getId());
        message.setCreateAt(LocalDateTime.now());
        message.setCreateBy(operatorId);
        message.setUpdateAt(LocalDateTime.now());
        message.setUpdateBy(operatorId);
        message.setNoticeType(0);
        message.setType(2);
        Map<String, Object> paramsToOwner = new HashMap<>();
        paramsToOwner.put("taskId", Optional.ofNullable(task.getId()).map(Object::toString).orElse(null));
        paramsToOwner.put("proId", Optional.ofNullable(task.getProId()).map(Object::toString).orElse(null));
        paramsToOwner.put("iterId", Optional.ofNullable(task.getIterId()).map(Object::toString).orElse(null));
        paramsToOwner.put("milestoneId", Optional.ofNullable(task.getMileId()).map(Object::toString).orElse(null));
        paramsToOwner.put("reqId", Optional.ofNullable(task.getReqId()).map(Object::toString).orElse(null));
        paramsToOwner.put("payloadType", "delete-task");
        paramsToOwner.put("title", task.getTitle());
        message.setParams(paramsToOwner);
        message.setStatus(1);
        message.setDeleted(0);
        messageService.sendMessage(message, List.of(task.getOwnerId()));
    }

    @Override
    public List<TaskVo> undoTaskList() {
        int loginId = StpUtil.getLoginIdAsInt();
        LambdaQueryWrapper<Task> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Task::getOwnerId, loginId)
                .ne(Task::getStatus, TaskConstant.TASK_STATUS_COMPLETED)
                .orderByAsc(Task::getEndTime)
                .orderByDesc(Task::getStartTime)
                .orderByDesc(Task::getUpdateAt);
        List<Task> taskList = taskMapper.selectList(queryWrapper);
        if (taskList.isEmpty()) {
            return Collections.emptyList();
        }

        // 获取用户信息
        List<Integer> userIdList = taskList.stream()
                .flatMap(task -> Stream.of(task.getOwnerId(), task.getCreateBy(), task.getUpdateBy()))
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());

        Map<Integer, UserVO> userVOMap = userService.listUserVoByIds(userIdList).stream()
                .collect(Collectors.toMap(UserVO::getId, userVO -> userVO));
        //获取附件数量
        List<Integer> taskIdList = taskList.stream().map(Task::getId).collect(Collectors.toList());
        List<AttachCount> attachCounts = new ArrayList<>();
        Map<Integer, AttachCount> attachCountMap = new HashMap<>();
        if (!taskIdList.isEmpty()) {
            attachCounts = attachesMapper.countByTaskIdList(taskIdList);
        }
        if (!attachCounts.isEmpty()) {
            attachCounts.forEach(attachCount -> attachCountMap.put(attachCount.getTypeId(), attachCount));
        }
        return taskList.stream().map(task -> {
            TaskVo taskVo = BeanUtil.copyProperties(task, TaskVo.class);
            taskVo.setOwner(userVOMap.get(task.getOwnerId()));
            taskVo.setCreator(userVOMap.get(task.getCreateBy()));
            taskVo.setUpdater(userVOMap.get(task.getUpdateBy()));
            AttachCount attachCount = attachCountMap.get(task.getId());
            taskVo.setAttachCount(attachCount != null ? attachCount.getCount() : 0);
            return taskVo;
        }).collect(Collectors.toList());
    }

    private List<TaskVo> listTasksByCondition(Integer mileId, Integer iterId, Integer proId) {
        if (Objects.isNull(iterId) && Objects.isNull(mileId) && Objects.isNull(proId)) {
            return Collections.emptyList();
        }
        LambdaQueryWrapper<Task> queryWrapper = new LambdaQueryWrapper<>();
        //项目下直接任务
        if (Objects.nonNull(proId) && Objects.isNull(mileId) && Objects.isNull(iterId)) {
            queryWrapper.eq(Task::getProId, proId);
            queryWrapper.isNull(Task::getMileId);
            queryWrapper.isNull(Task::getIterId);
            queryWrapper.isNull(Task::getReqId);
        }
        //里程碑下直接任务
        else if (Objects.nonNull(mileId)) {
            queryWrapper.eq(Task::getMileId, mileId);
            queryWrapper.isNull(Task::getIterId);
            queryWrapper.isNull(Task::getReqId);
        }
        //迭代下直接任务
        else if (Objects.nonNull(iterId)) {
            queryWrapper.eq(Task::getIterId, iterId);
            queryWrapper.isNull(Task::getReqId);
        }

        queryWrapper.eq(Task::getDeleted, 0)
                .orderByAsc(Task::getPriority)
                .orderByAsc(Task::getStartTime)
                .orderByAsc(Task::getEndTime)
                .orderByAsc(Task::getStatus)
                .orderByAsc(Task::getCreateAt)
                .orderByAsc(Task::getUpdateAt)
                .orderByAsc(Task::getId);

        List<Task> taskList = taskMapper.selectList(queryWrapper);
        if (taskList.isEmpty()) {
            return Collections.emptyList();
        }

        // 获取用户信息
        List<Integer> userIdList = taskList.stream()
                .flatMap(task -> Stream.of(task.getOwnerId(), task.getCreateBy(), task.getUpdateBy()))
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());

        Map<Integer, UserVO> userVOMap = userService.listUserVoByIds(userIdList).stream()
                .collect(Collectors.toMap(UserVO::getId, userVO -> userVO));
        //获取附件数量
        List<Integer> taskIdList = taskList.stream().map(Task::getId).collect(Collectors.toList());
        List<AttachCount> attachCounts = new ArrayList<>();
        Map<Integer, AttachCount> attachCountMap = new HashMap<>();
        if (!taskIdList.isEmpty()) {
            attachCounts = attachesMapper.countByTaskIdList(taskIdList);
        }
        if (!attachCounts.isEmpty()) {
            attachCounts.forEach(attachCount -> attachCountMap.put(attachCount.getTypeId(), attachCount));
        }
        return taskList.stream().map(task -> {
            TaskVo taskVo = BeanUtil.copyProperties(task, TaskVo.class);
            taskVo.setOwner(userVOMap.get(task.getOwnerId()));
            taskVo.setCreator(userVOMap.get(task.getCreateBy()));
            taskVo.setUpdater(userVOMap.get(task.getUpdateBy()));
            AttachCount attachCount = attachCountMap.get(task.getId());
            taskVo.setAttachCount(attachCount != null ? attachCount.getCount() : 0);
            return taskVo;
        }).collect(Collectors.toList());
    }
}




